<?php

namespace App\Model\Article;

use EasySwoole\Mysqli\QueryBuilder;
use EasySwoole\ORM\ {
    AbstractModel,
    Utility\Schema\Table,
};
use App\Model\Base;

use App\Common\Tools;

/**
 * 文章
 * Class Article
 */
class Article extends Base
{
    protected $tableName = 'article';

    /**
     * 表的字段
     * 此处需要返回一个 EasySwoole\ORM\Utility\Schema\Table
     * @return Table
     */
    public function schemaInfo(bool $isCache = true): Table
    {
        $table = new Table($this->tableName);
        $table->colInt('id')->setIsPrimaryKey(true);
        $table->colVarChar('name', 50);
        $table->colLongText('content');
        $table->colSmallInt('navs_id');
        $table->colTinyInt('display');
        $table->colVarChar('keywords', 255);
        $table->colVarChar('description', 500);
        $table->colInt('read_number', 11);
        $table->colDate('update_time');
        $table->colTinyInt('content_type');
        /* alter table article drop sort, modify display tinyint(1) default 0 comment '0、显示 1、不显示',
        modify navs_id smallint unsigned comment '分类id';
        */
        return $table;
    }

    /**
     * @description: 关联文章分类
     * @param {*}
     * @return {*}
     */
    public function nav()
    {
        return $this->hasOne(Nav::class, function(QueryBuilder $query){
            $query->fields(['id', 'name']);
            return $query;
        }, 'navs_id', 'id');
    }


    /**
     * @description: 范围查询条件
     * @param {*}
     * @return {*}
     */
    public function scopWhere()
    {
        $this->where('display', 0);
        return $this;
    }

    /**
     * @description: 获取最新发布文章
     * @param {*}
     * @return {*}
     */
    public function getNews($limit = 15)
    {
        return static::tryCatch(function($limit) {
            return $this->scopWhere()->field('id,name,update_time')->limit($limit)
                        ->order('update_time', 'desc')->all()->toArray();
        }, [], $limit);
    }

    /**
     * @description: 获取本周最新发布文章
     * @param {*}
     * @return {*}
     */
    public function getWeeks($limit = 15)
    {
        return static::tryCatch(function($limit) {
            $w     = date('w') ?: 7;
            $week  = date('Y-m-d', strtotime('-' . $w . 'day'));
            $where = ['update_time' => [$week, '>=']];
            return $this->scopWhere()->where($where)->field('id,name,update_time')->limit($limit)
                        ->order('update_time', 'desc')->all()->toArray();
        }, [], $limit);
    }

    /**
     * @description: 获取本月最新发布文章
     * @param {*}
     * @return {*}
     */
    public function getMonths($limit = 15)
    {
        return static::tryCatch(function($limit) {
            $where = ['update_time' => [date('Y-m-01'), '>=']];
            return $this->scopWhere()->where($where)->field('id,name,update_time')->limit($limit)
                        ->order('update_time', 'desc')->all()->toArray();
        }, [], $limit);    
    }

    /**
     * @description: 获取文章，分页显示
     * @param int $page 页码
     * @param int $limit 每页数量
     * @param array $where 查询条件
     * @return {*}
     */
    public function getAricles(int $page, int $limit, array $where = [])
    {
        return static::tryCatch(function($page, $limit, $where) {
            $model = $this->with(['nav'])->scopWhere()->where($where)
                    ->order('update_time', 'desc')->order('id', 'desc')
                    ->field(['id,name,update_time,navs_id'])
                    ->limit($limit * ($page - 1), $limit)->withTotalCount();

            $list   = $model->all(null);
            $datas  = $list->toArray();
            $result = $model->lastQueryResult();
            $total  = $result->getTotalCount();
            foreach ($list as $key => $val) {
                $datas[$key]['nav_name'] = $val->nav->name;
            }
            return [$datas, $total];
        }, [[], 0], $page, $limit, $where);   
    }


    /**
     * @description: 获取文章，分页显示
     * @param int $page 页码
     * @param int $limit 每页数量
     * @param array $where 查询条件
     * @return {*}
     */
    public function getTheme1Aricles(int $page, int $limit, string $search = '', array $nav_ids = [])
    {
        return static::tryCatch(function($page, $limit, $search, $nav_ids) {
            $model = $this->with(['nav'])->scopWhere();
            if ($nav_ids) {
                $model = $model->where('id', $nav_ids, 'IN');
            }
            if ($search) {
                $searchContent = '%' . $search . '%';
                $model = $model->where("MATCH (name,content,keywords,description) AGAINST (+'" . $search . "' IN BOOLEAN MODE)")
                    ->where('title', [$searchContent, 'like'], '', 'OR')
                    ->where('content', [$searchContent, 'like'], '', 'OR');
            }
            $model = $model->order('update_time', 'desc')->order('id', 'desc')
                    ->field(['id,name,update_time,navs_id'])
                    ->limit($limit * ($page - 1), $limit)->withTotalCount();

            $list   = $model->all(null);
            $datas  = $list->toArray();
            $result = $model->lastQueryResult();
            $total  = $result->getTotalCount();
            foreach ($list as $key => $val) {
                $datas[$key]['nav_name'] = $val->nav->name;
            }
            return [$datas, $total];
        }, [[], 0], $page, $limit, $search, $nav_ids);   
    }
    
    /**
     * @description: 获取最新文章
     * @param array $where 查询条件
     * @param int $limit 每页数量
     * @return {*}
     */
    public function getAricleNews($where, int $limit = 5)
    {
        return static::tryCatch(function($where, $limit) {
            return $this->scopWhere()->where($where)->order('update_time', 'desc')->order('id', 'asc')
                    ->field(['id,name'])->limit($limit)->all()->toArray();
        }, [], $where, $limit); 
    }

    /**
     * @description: 获取指定指定文章
     * @param int $id 文章id
     * @return {*}
     */
    public function getDetails(int $id)
    {
        return static::tryCatch(function($id) {
            $art = $this->with(['nav'])->where('id', $id)->get();
            if (!$art) {
                return [];
            }
            $nav_name = $art->nav->name;
            $art = $art->toArray();
            $art['nav_name'] = $nav_name;
            return $art;
        }, [], $id); 
    }

    /**
     * @description: 获取上一篇文章
     * @param int $id 文章id
     * @return {*}
     */
    public function getPrevious(int $id)
    {
        return static::tryCatch(function($id) {
            $art = $this->where('id', $id)->field(['id', 'update_time', 'navs_id'])->get();
            $where = [
                'navs_id'     => $art['navs_id'],
                'update_time' => [$art['update_time'], '>='],
                'id'          => [$art['id'], '>'],
            ];
            return $this->scopWhere()->where($where)->field(['id', 'name'])
                    ->order('update_time', 'asc')->order('id', 'asc')->get()->toArray();
        }, [], $id);
    }

    /**
     * @description: 获取下一篇文章
     * @param int $id 文章id
     * @return {*}
     */
    public function getNext(int $id)
    {
        return static::tryCatch(function($id) {
            $art = $this->where('id', $id)->field(['id', 'update_time', 'navs_id'])->get();
            $where = [
                'navs_id'     => $art['navs_id'],
                'update_time' => [$art['update_time'], '<='],
                'id'          => [$art['id'], '<'],
            ];
            return $this->scopWhere()->where($where)->field(['id', 'name'])
                    ->order('update_time', 'desc')->order('id', 'desc')->get()->toArray();
        }, [], $id);
    }

    /**
     * @description: 分页列表连贯查询
     * @param {*}
     * @return {*}
     */    
    protected function adminPagesCoherent()
    {
        $field = ['id', 'name', 'navs_id', 'read_number', 'update_time', 'display', 'content_type'];
        $this->with(['nav'])->field($field)->order('read_number', 'desc')->order('update_time', 'desc');
        return $this;
    }

    /**
     * @description: 分页列表数据处理
     * @param {*}
     * @return {*}
     */    
    protected function adminPagesData($list)
    {
        $datas = $list->toArray();
        foreach ($list as $key => $val) {
            $datas[$key]['nav_name'] = $val->nav->name;
        }
        return $datas;
    }

    /**
     * @description: 拼接创建参数
     * @param {*}
     * @return {*}
     */
    protected function createDatas()
    {
        $data = [
            'name'        => $this->param['name'],
            'content'     => $this->param['content'],
            'navs_id'     => $this->param['navs_id'],
            'display'     => $this->param['display'],
            'keywords'    => $this->param['keywords'],
            'description' => $this->param['description'],
            'content_type' => $this->param['content_type'],
        ];
        if (!Tools::hasValue($this->param, 'id')) {
            $data['update_time'] = date('Y-m-d');
        }
        return $data;
    }
 
    /**
     * @description: 空数据
     * @param {*}
     * @return {*}
     */
    public function nullData()
    {
        return [
            'id'          => '',
            'name'        => '',
            'content'     => '',
            'update_time' => '',
            'navs_id'     => '',
            'display'     => '',
            'keywords'    => '',
            'description' => '',
            'read_number' => '',
        ];
    }

    /**
     * @description: 获取首页分类下文章
     * @param {*}
     * @return {*}
     */
    public function getHomeTheme1Arts()
    {
        return static::tryCatch(function() {
            return $this->scopWhere()->limit(10)
                ->order('update_time', 'desc')->all()->toArray();
        }, [], []);
    }
}